package com.attendance.www.hr.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import com.attendance.www.hr.beans.EmployeeBean;
import com.attendance.www.hr.beans.ModifyLogsBean;
import com.attendance.www.hr.beans.ModifyLogsPageBean;
import com.attendance.www.hr.constant.AppConstant;
import com.attendance.www.hr.dao.mapper.AttachmentMapper;
import com.attendance.www.hr.dao.mapper.EmployeeExtMapper;
import com.attendance.www.hr.dao.mapper.EmployeeMapper;
import com.attendance.www.hr.dao.mapper.FurloughBalanceMapper;
import com.attendance.www.hr.dao.mapper.ModifyLogsExtMapper;
import com.attendance.www.hr.dao.mapper.ModifyLogsMapper;
import com.attendance.www.hr.entitys.Attachment;
import com.attendance.www.hr.entitys.Employee;
import com.attendance.www.hr.entitys.FurloughBalance;
import com.attendance.www.hr.entitys.FurloughBalanceExample;
import com.attendance.www.hr.entitys.ModifyLogs;
import com.attendance.www.hr.entitys.ModifyLogsExample;
import com.attendance.www.hr.exception.ResultFaultException;
import com.attendance.www.hr.service.IModifyService;
import com.attendance.www.hr.utils.ArithUtil;

@Service
public class ModifyServiceImpl implements IModifyService {

	@Resource
	private ModifyLogsMapper modifyLogsDao;
	@Resource
	private EmployeeMapper employeeDao;
	@Resource
	private FurloughBalanceMapper furloughBalanceDao;
	@Resource
	private ModifyLogsExtMapper modifyLogsExtDao;
	@Resource
	private AttachmentMapper attachmentDao;
	@Resource
	private EmployeeExtMapper employeeExtDao;

	/**
	 * 查询员工调休剩余额度
	 */
	@Override
	public ModifyLogsPageBean getRestBalanceList(ModifyLogsBean modifyLogsBean) {
		ModifyLogsPageBean mlpb = new ModifyLogsPageBean();
		mlpb.setModifyLogsBeanList(modifyLogsExtDao.getRestBalanceList(new Date(), modifyLogsBean));
		mlpb.setPageTotal(modifyLogsExtDao.count(modifyLogsBean));
		return mlpb;
	}

	/**
	 * 查询调整调休额度logs
	 */
	@Override
	public List<ModifyLogsBean> getModifyLogsList(String employeeNo) {
		ModifyLogsExample mExample = new ModifyLogsExample();
		mExample.createCriteria().andEmployeeNoEqualTo(employeeNo);
		mExample.setOrderByClause("create_time desc");
		List<ModifyLogs> modifyLogsList = modifyLogsDao.selectByExample(mExample);
		List<ModifyLogsBean> mlbList = new ArrayList<>();
		for (ModifyLogs modifyLogs : modifyLogsList) {
			ModifyLogsBean modifyLogsBean = new ModifyLogsBean();
			modifyLogsBean.setChineseName(modifyLogs.getChineseName());
			modifyLogsBean.setCreateTime(modifyLogs.getCreateTime());
			modifyLogsBean.setEmployeeNo(modifyLogs.getEmployeeNo());
			modifyLogsBean.setMinutes(modifyLogs.getMinutes());
			modifyLogsBean.setMinutesStr(modifyLogs.getMinutes().toString());
			modifyLogsBean.setModifyChineseName(modifyLogs.getModifyChineseName());
			modifyLogsBean.setModifyEmployeeNo(modifyLogs.getModifyEmployeeNo());
			modifyLogsBean.setDescription(modifyLogs.getDescription());
			mlbList.add(modifyLogsBean);
		}
		return mlbList;
	}

	/**
	 * 调整调休余额；并新增调整调休（加班）额度记录
	 */
	@Override
	public boolean saveModifyLogs(ModifyLogsBean modifyLogsBean) {
		FurloughBalanceExample furloughBalanceExample=new FurloughBalanceExample();
		furloughBalanceExample.createCriteria().andEmployeeIdEqualTo(modifyLogsBean.getEmployeeId())
		.andFurloughBalanceTypeEqualTo(0);
		int count=furloughBalanceDao.countByExample(furloughBalanceExample);
		if(count>0) {
			// 被调整人的ID
			Integer employeeId = modifyLogsBean.getEmployeeId();
			// 调整调休余额
			FurloughBalanceExample example = new FurloughBalanceExample();
			example.createCriteria().andEmployeeIdEqualTo(employeeId).andFurloughBalanceTypeEqualTo(0);
			FurloughBalance furloughBalance = new FurloughBalance();
			furloughBalance.setBalanceHoursDay(modifyLogsBean.getAfterBalanceHoursDay());
			int record = furloughBalanceDao.updateByExampleSelective(furloughBalance, example);
			if (record <= 0) {
				return false;
			}
		}else {
			FurloughBalance furloughBalance = new FurloughBalance();
			furloughBalance.setFurloughBalanceType(0);
			furloughBalance.setEmployeeId(modifyLogsBean.getEmployeeId());
			furloughBalance.setBalanceHoursDay(modifyLogsBean.getAfterBalanceHoursDay());
			furloughBalance.setInitHoursDay(modifyLogsBean.getAfterBalanceHoursDay());
			furloughBalanceDao.insertSelective(furloughBalance);
		}
		
		// 做调整操作人的ID
		Integer modifyEmployeeId = modifyLogsBean.getModifyEmployeeId();
		// 新增调整调休（加班）额度记录
		ModifyLogs modifyLogs = new ModifyLogs();
		modifyLogs.setChineseName(modifyLogsBean.getChineseName());
		modifyLogs.setEmployeeNo(modifyLogsBean.getEmployeeNo());
		modifyLogs.setMinutes(modifyLogsBean.getMinutes());
		modifyLogs.setDescription(modifyLogsBean.getDescription());
		if (modifyEmployeeId == null) {// 管理员
			modifyLogs.setModifyChineseName("admin");
		} else {
			Employee employee = employeeDao.selectByPrimaryKey(modifyEmployeeId);
			modifyLogs.setModifyChineseName(employee.getChineseName());
			modifyLogs.setModifyEmployeeNo(employee.getEmployeeNo());
		}
		modifyLogs.setModifyEmployeeNo(modifyLogsBean.getModifyEmployeeNo());
		int record = modifyLogsDao.insertSelective(modifyLogs);
		if (record <= 0) {
			return false;
		}
		return true;
	}

	/**
	 * 调休余额导入
	 * 
	 * @param attachmentId
	 * @param employeeId
	 * @return
	 */
	@Override
	public List<String> modifyImport(Integer attachmentId, Integer employeeId) {
		List<String> successList = new ArrayList<String>();
		// 查询附件表获取路径地址
		Attachment attachment = attachmentDao.selectByPrimaryKey(attachmentId);
		// 设置文件路径
		String pathName = attachment.getUrl().replace(AppConstant.UPLOAD_RESOURCE, AppConstant.SAVE_FILE_REPOSITORY);
		File file = new File(pathName);
		Workbook work = null;
		if (file.exists()) {
			try {
				InputStream inputStream = new FileInputStream(file);
				if (pathName.matches("^.+\\.(?i)(xls)$")) {
					work = new HSSFWorkbook(inputStream);
				} else if (pathName.matches("^.+\\.(?i)(xlsx)$")) {
					work = new XSSFWorkbook(inputStream);
				}
			} catch (Exception ex) {
				throw new ResultFaultException("0_00003");
			}
		} else {
			throw new ResultFaultException("0_00003");
		}
		if (work == null) {
			throw new ResultFaultException("0_00003");
		}

		if (work != null) {
			successList = addModify(work, successList, employeeId);
		}
		return successList;
	}

	/**
	 * 导入excel表格，逐行读取操作
	 * 
	 * @param work12
	 * @param successList
	 * @param employeeId
	 * @return
	 */
	private List<String> addModify(Workbook work, List<String> successList, Integer employeeId) {
		List<EmployeeBean> employeeBeanList = employeeExtDao.getEmployeePageList(new EmployeeBean(), null, null);
		List<FurloughBalance> furloughBalanceList = new ArrayList<FurloughBalance>();
		if (employeeBeanList != null) {
			List<Integer> employeeIdList = employeeBeanList.stream().map(EmployeeBean::getEmployeeId)
					.collect(Collectors.toList());
			;
			if (employeeIdList.size() > 0) {
				FurloughBalanceExample furloughBalanceExample = new FurloughBalanceExample();
				furloughBalanceExample.createCriteria().andEmployeeIdIn(employeeIdList)
						.andFurloughBalanceTypeEqualTo(0);
				furloughBalanceList = furloughBalanceDao.selectByExample(furloughBalanceExample);
			}
		}
		List<ModifyLogsBean> modifyLogsBeanList = new ArrayList<ModifyLogsBean>();
		// 获取工作表的数量
		int sheetNum = work.getNumberOfSheets();
		// 遍历工作表 找出要导入的Excel表
		for (int m = 0; m < sheetNum; m++) {
			Sheet sh = work.getSheetAt(m);
			if (sh.getSheetName().equals("调休余额信息")) {
				Sheet sheet = work.getSheetAt(m);
				List<String> errorMsgList = new ArrayList<String>();// 创建错误信息列表
				// 单元格
				String cellValue = "";
				// 获取班次标题和获取法定节假日
				Row row = sheet.getRow(0);
				// 循环获取Excel每行的每个单元格
				for (int i = 1; i <= sheet.getLastRowNum() + 1; i++) {
					StringBuilder stringBuilder = new StringBuilder("第" + (i + 1) + "行：");
					row = sheet.getRow(i);
					// 如果一整行为空则忽略此行继续遍历
					if (row == null) {
						continue;
					}
					// 遍历某一行的所有列，如果此行每列都为空则跳过继续下一行
					boolean isNull = true;
					for (int c = 0; c < row.getLastCellNum(); c++) {
						if (row.getCell(c) == null || StringUtils.isBlank(row.getCell(c).toString())) {
							continue;
						} else {
							isNull = false;
						}
					}
					if (isNull) {
						continue;
					}

					ModifyLogsBean modifyLogsBean = new ModifyLogsBean();
					// 列号
					int columns = 0;
					// 工号号
					if (row.getCell(columns) != null && StringUtils.isNotBlank(row.getCell(columns).toString())) {
						// 判断是否为数字
						if (row.getCell(columns).getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
							cellValue = new BigDecimal(row.getCell(columns).getNumericCellValue()).intValue() + "";
						} else {
							cellValue = row.getCell(columns).toString();
						}
						if (cellValue.length() <= 4) {
							cellValue = "0" + cellValue;
						}
						final String value = cellValue.toString();
						// 验证员工号是否存在
						List<EmployeeBean> ebList = employeeBeanList.stream()
								.filter(s -> s.getEmployeeNo().equals(value)).collect(Collectors.toList());
						if (ebList.size() > 0) {
							modifyLogsBean.setEmployeeId(ebList.get(0).getEmployeeId());
							modifyLogsBean.setChineseName(ebList.get(0).getChineseName());
							modifyLogsBean.setEmployeeNo(ebList.get(0).getEmployeeNo());
						} else {
							stringBuilder.append("员工号("+value+")不存在,");
						}
					} else {
						stringBuilder.append("员工号不能为空,");
					}
					columns = 2;
					// 余额
					if (row.getCell(columns) != null && StringUtils.isNotBlank(row.getCell(columns).toString())) {
						BigDecimal number = null;
						BigDecimal afterBalanceHoursDay = null;
						BigDecimal balanceHoursDay=new BigDecimal(0);
						try {
							// 判断是否为数字
							if (row.getCell(columns).getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
								number = new BigDecimal(row.getCell(columns).getNumericCellValue());
							} else {
								number = new BigDecimal(row.getCell(columns).toString());
							}
							// 计算分钟数 整数-减（如果小于0则，不通过），负数-加
							List<FurloughBalance> fbList = furloughBalanceList.stream()
									.filter(s -> s.getEmployeeId().equals(modifyLogsBean.getEmployeeId()))
									.collect(Collectors.toList());
							if (fbList.size() > 0) {
								balanceHoursDay=fbList.get(0).getBalanceHoursDay();
							}
							// 和0，ZERO比较
							int r = number.compareTo(BigDecimal.ZERO);
							// 负数
							if (r < 0) {
								afterBalanceHoursDay = ArithUtil.add(balanceHoursDay,number.abs());
								modifyLogsBean.setAfterBalanceHoursDay(afterBalanceHoursDay);
							} else {
								// 验证员工是否有调休余额
								if(modifyLogsBean.getEmployeeId()!=null) {
									FurloughBalanceExample furloughBalanceExample=new FurloughBalanceExample();
									furloughBalanceExample.createCriteria().andEmployeeIdEqualTo(modifyLogsBean.getEmployeeId())
									.andFurloughBalanceTypeEqualTo(0);
									int count=furloughBalanceDao.countByExample(furloughBalanceExample);
									if(count<=0) {
										stringBuilder.append("员工号("+modifyLogsBean.getEmployeeNo()+")无调休余额,");
									}else {
										// 整数
										afterBalanceHoursDay = ArithUtil.sub(balanceHoursDay, number);
										if (afterBalanceHoursDay.compareTo(BigDecimal.ZERO) < 0) {
											stringBuilder.append("余额不能为负(" + afterBalanceHoursDay.toString() + "),");
										} else {
											modifyLogsBean.setAfterBalanceHoursDay(afterBalanceHoursDay);
										}
									}
								}
							}
							//modifyLogsBean.setDescription("管理员模板导入");
							modifyLogsBean.setMinutes(number);
						} catch (Exception e) {
							stringBuilder.append("余额格式不正确,");
						}
					} else {
						stringBuilder.append("余额不能为空,");
					}
					columns++;
					// 备注
					if (row.getCell(columns) != null && StringUtils.isNotBlank(row.getCell(columns).toString())) {
						cellValue = row.getCell(columns).toString();
						modifyLogsBean.setDescription(cellValue);
					}

					// 判断错误信息长度
					if (stringBuilder.length() != new String("第" + (i + 1) + "行：").length()) {
						String errorStr = stringBuilder.toString().substring(0, stringBuilder.toString().length() - 1);
						errorMsgList.add(errorStr);
					} else {
						modifyLogsBeanList.add(modifyLogsBean);
					}
				}

				if (errorMsgList.size() > 0) {
					throw new ResultFaultException("20_00001", errorMsgList);
				} else {
					// 循环保存
					for (ModifyLogsBean modifyLogsBean : modifyLogsBeanList) {
						this.saveModifyLogs(modifyLogsBean);
					}
				}
				successList.add(0, "导入完成。");
				return successList;
			}
		}
		throw new ResultFaultException("0_00014");
	}
}
